home *** CD-ROM | disk | FTP | other *** search
- // X mode Graphics library
- // by Karl Lager
- // Sept, 1996
-
- // initialize graphics, set resolution, plot point,
- // blit image with zoom, flip, rotate, and clipping
-
-
- // If you want to contact me with any questions or comments about this
- // code, leave a message in the CompuServe gamedev forum (GO GAMEDEV)
- // section 3 (DOS games) addressed to 76752,2243
-
-
- #include <dos.h>
- #include <math.h>
-
- // from Tweak.zip
- //----------------------------------------------------------------------
- //#include "TwkUser.h" // get Register definition
-
- /*
- xxxxADDR defines the base port number used to access VGA component xxxx,
- and is defined for xxxx =
- ATTRCON - Attribute Controller
- MISC - Miscellaneous Register
- VGAENABLE - VGA Enable Register
- SEQ - Sequencer
- GRACON - Graphics Controller
- CRTC - Cathode Ray Tube Controller
- STATUS - Status Register
- */
-
- #define ATTRCON_ADDR 0x3c0
- #define MISC_ADDR 0x3c2
- #define VGAENABLE_ADDR 0x3c3
- #define SEQ_ADDR 0x3c4
- #define GRACON_ADDR 0x3ce
- #define CRTC_ADDR 0x3d4
- #define STATUS_ADDR 0x3da
-
-
- /*
- Note that the following C definition of Register is not compatible
- with the C++ definition used in the source code of TWEAK itself!
- */
-
- typedef struct
- {
- unsigned port;
- unsigned char index;
- unsigned char value;
- } Register;
-
- typedef Register *RegisterPtr;
-
-
-
- Register mode320x200[] =
- {
- { 0x3c2, 0x0, 0x63},
- { 0x3d4, 0x0, 0x5f},
- { 0x3d4, 0x1, 0x4f},
- { 0x3d4, 0x2, 0x50},
- { 0x3d4, 0x3, 0x82},
- { 0x3d4, 0x4, 0x54},
- { 0x3d4, 0x5, 0x80},
- { 0x3d4, 0x6, 0xbf},
- { 0x3d4, 0x7, 0x1f},
- { 0x3d4, 0x8, 0x0},
- { 0x3d4, 0x9, 0x41},
- { 0x3d4, 0x10, 0x9c},
- { 0x3d4, 0x11, 0x8e},
- { 0x3d4, 0x12, 0x8f},
- { 0x3d4, 0x13, 0x28},
- { 0x3d4, 0x14, 0x0},
- { 0x3d4, 0x15, 0x96},
- { 0x3d4, 0x16, 0xb9},
- { 0x3d4, 0x17, 0xe3},
- { 0x3c4, 0x1, 0x1},
- { 0x3c4, 0x4, 0x6},
- { 0x3ce, 0x5, 0x40},
- { 0x3ce, 0x6, 0x5},
- { 0x3c0, 0x10, 0x41},
- { 0x3c0, 0x13, 0x0}
- };
-
- Register mode320x240[] =
- {
- { 0x3c2, 0x0, 0xe3},
- { 0x3d4, 0x0, 0x5f},
- { 0x3d4, 0x1, 0x4f},
- { 0x3d4, 0x2, 0x50},
- { 0x3d4, 0x3, 0x82},
- { 0x3d4, 0x4, 0x54},
- { 0x3d4, 0x5, 0x80},
- { 0x3d4, 0x6, 0xd},
- { 0x3d4, 0x7, 0x3e},
- { 0x3d4, 0x8, 0x0},
- { 0x3d4, 0x9, 0x41},
- { 0x3d4, 0x10, 0xea},
- { 0x3d4, 0x11, 0xac},
- { 0x3d4, 0x12, 0xdf},
- { 0x3d4, 0x13, 0x28},
- { 0x3d4, 0x14, 0x0},
- { 0x3d4, 0x15, 0xe7},
- { 0x3d4, 0x16, 0x6},
- { 0x3d4, 0x17, 0xe3},
- { 0x3c4, 0x1, 0x1},
- { 0x3c4, 0x4, 0x6},
- { 0x3ce, 0x5, 0x40},
- { 0x3ce, 0x6, 0x5},
- { 0x3c0, 0x10, 0x41},
- { 0x3c0, 0x13, 0x0}
- };
-
- Register mode320x400[] =
- {
- { 0x3c2, 0x0, 0x63},
- { 0x3d4, 0x0, 0x5f},
- { 0x3d4, 0x1, 0x4f},
- { 0x3d4, 0x2, 0x50},
- { 0x3d4, 0x3, 0x82},
- { 0x3d4, 0x4, 0x54},
- { 0x3d4, 0x5, 0x80},
- { 0x3d4, 0x6, 0xbf},
- { 0x3d4, 0x7, 0x1f},
- { 0x3d4, 0x8, 0x0},
- { 0x3d4, 0x9, 0x40},
- { 0x3d4, 0x10, 0x9c},
- { 0x3d4, 0x11, 0x8e},
- { 0x3d4, 0x12, 0x8f},
- { 0x3d4, 0x13, 0x28},
- { 0x3d4, 0x14, 0x0},
- { 0x3d4, 0x15, 0x96},
- { 0x3d4, 0x16, 0xb9},
- { 0x3d4, 0x17, 0xe3},
- { 0x3c4, 0x1, 0x1},
- { 0x3c4, 0x4, 0x6},
- { 0x3ce, 0x5, 0x40},
- { 0x3ce, 0x6, 0x5},
- { 0x3c0, 0x10, 0x41},
- { 0x3c0, 0x13, 0x0}
- };
- Register mode360x270[] =
- {
- { 0x3c2, 0x0, 0xe7},
- { 0x3d4, 0x0, 0x6b},
- { 0x3d4, 0x1, 0x59},
- { 0x3d4, 0x2, 0x5a},
- { 0x3d4, 0x3, 0x8e},
- { 0x3d4, 0x4, 0x5e},
- { 0x3d4, 0x5, 0x8a},
- { 0x3d4, 0x6, 0x30},
- { 0x3d4, 0x7, 0xf0},
- { 0x3d4, 0x8, 0x0},
- { 0x3d4, 0x9, 0x61},
- { 0x3d4, 0x10, 0x20},
- { 0x3d4, 0x11, 0xa9},
- { 0x3d4, 0x12, 0x1b},
- { 0x3d4, 0x13, 0x2d},
- { 0x3d4, 0x14, 0x0},
- { 0x3d4, 0x15, 0x1f},
- { 0x3d4, 0x16, 0x2f},
- { 0x3d4, 0x17, 0xe3},
- { 0x3c4, 0x1, 0x1},
- { 0x3c4, 0x4, 0x6},
- { 0x3ce, 0x5, 0x40},
- { 0x3ce, 0x6, 0x5},
- { 0x3c0, 0x10, 0x41},
- { 0x3c0, 0x13, 0x0}
- };
-
- Register mode400x300[] =
- {
- { 0x3c2, 0x0, 0xa7},
- { 0x3d4, 0x0, 0x71},
- { 0x3d4, 0x1, 0x63},
- { 0x3d4, 0x2, 0x64},
- { 0x3d4, 0x3, 0x92},
- { 0x3d4, 0x4, 0x65},
- { 0x3d4, 0x5, 0x82},
- { 0x3d4, 0x6, 0x46},
- { 0x3d4, 0x7, 0x1f},
- { 0x3d4, 0x8, 0x0},
- { 0x3d4, 0x9, 0x40},
- { 0x3d4, 0x10, 0x31},
- { 0x3d4, 0x11, 0x80},
- { 0x3d4, 0x12, 0x2b},
- { 0x3d4, 0x13, 0x32},
- { 0x3d4, 0x14, 0x0},
- { 0x3d4, 0x15, 0x2f},
- { 0x3d4, 0x16, 0x44},
- { 0x3d4, 0x17, 0xe3},
- { 0x3c4, 0x1, 0x1},
- { 0x3c4, 0x2, 0xf},
- { 0x3c4, 0x4, 0x6},
- { 0x3ce, 0x5, 0x40},
- { 0x3ce, 0x6, 0x5},
- { 0x3c0, 0x10, 0x41},
- { 0x3c0, 0x13, 0x0}
- };
-
-
- /*
- readyVgaRegs() does the initialization to make the VGA ready to
- accept any combination of configuration register settings.
-
- This involves enabling writes to index 0 to 7 of the CRT controller
- (port 0x3d4), by clearing the most significant bit (bit 7) of index
- 0x11.
- */
-
- void readyVgaRegs(void)
- {
- int v;
- outportb(0x3d4,0x11);
- v = inportb(0x3d5) & 0x7f;
- outportb(0x3d4,0x11);
- outportb(0x3d5,v);
- }
-
- /*
- outReg sets a single register according to the contents of the
- passed Register structure.
- */
-
- void outReg(Register r)
- {
- switch (r.port)
- {
- /* First handle special cases: */
-
- case ATTRCON_ADDR:
- inportb(STATUS_ADDR); /* reset read/write flip-flop */
- outportb(ATTRCON_ADDR, r.index | 0x20);
- /* ensure VGA output is enabled */
- outportb(ATTRCON_ADDR, r.value);
- break;
-
- case MISC_ADDR:
- case VGAENABLE_ADDR:
- outportb(r.port, r.value); /* directly to the port */
- break;
-
- case SEQ_ADDR:
- case GRACON_ADDR:
- case CRTC_ADDR:
- default: /* This is the default method: */
- outportb(r.port, r.index); /* index to port */
- outportb(r.port+1, r.value);/* value to port+1 */
- break;
- }
- }
-
-
- /*
- outRegArray sets n registers according to the array pointed to by r.
- First, indexes 0-7 of the CRT controller are enabled for writing.
- */
-
- void outRegArray(Register *r, int n)
- {
- readyVgaRegs();
- while (n--)
- outReg(*r++);
- }
-
- //----------------------------------------------------------------------
- // * The above is from Tweak.zip by Robert Schmidt
- // * See Tweak.zip in the compuserve Gamedev forum hardware library
-
-
- int maxx, maxy; // screen resolution
- int xmin,ymin,xmax,ymax; // scp window
- int pagewidth,pageheight,pagesize;
- char *vga=(char*) MK_FP(0xA000, 0);
- char *activepage, *visiblepage;
- unsigned activestart,visiblestart;
-
- #define setmin(a,b) if (b<a) a=b
- #define setmax(a,b) if (b>a) a=b
-
- void initgraphics()
- { union REGS r;
-
- /* Set VGA BIOS mode 13h: */
-
- r.x.ax = 0x0013;
- int86(0x10, &r, &r);
- }
- // note: the initgraphics function is necesssary to set the palette properly.
- // It also resets the palette whenever called.
-
-
- void set320x200()
- {
- outRegArray(mode320x200,25);
-
- maxx = 319;
- maxy = 199;
- xmin = 0;
- ymin = 0;
- xmax = maxx;
- ymax = maxy;
- pagewidth = (maxx+1)/4;
- pageheight = maxy+1;
- pagesize = pagewidth * pageheight;
- visiblepage = vga;
- activepage = vga+pagesize;
- }
- void set320x240()
- {
- outRegArray(mode320x240,25);
-
- maxx = 319;
- maxy = 239;
- xmin = 0;
- ymin = 0;
- xmax = maxx;
- ymax = maxy;
- pagewidth = (maxx+1)/4;
- pageheight = maxy+1;
- pagesize = pagewidth * pageheight;
- visiblepage = vga;
- activepage = vga+pagesize;
- }
- void set320x400()
- {
- outRegArray(mode320x400,25);
-
- maxx = 319;
- maxy = 399;
- xmin = 0;
- ymin = 0;
- xmax = maxx;
- ymax = maxy;
- pagewidth = (maxx+1)/4;
- pageheight = maxy+1;
- pagesize = pagewidth * pageheight;
- visiblepage = vga;
- activepage = vga+pagesize;
- }
- void set360x270()
- { outRegArray(mode360x270,25);
-
- maxx = 359;
- maxy = 269;
- xmin = 0;
- ymin = 0;
- xmax = maxx;
- ymax = maxy;
- pagewidth = (maxx+1)/4;
- pageheight = maxy+1;
- pagesize = pagewidth * pageheight;
- visiblepage = vga;
- activepage = vga+pagesize;
- }
-
- void set400x300()
- { outRegArray(mode400x300,25);
-
- maxx = 399;
- maxy = 299;
- xmin = 0;
- ymin = 0;
- xmax = maxx;
- ymax = maxy;
- pagewidth = (maxx+1)/4;
- pageheight = maxy+1;
- pagesize = pagewidth * pageheight;
- visiblepage = vga;
- activepage = vga+pagesize;
- }
-
-
- void set80x25(void) // restore text
- {
- union REGS r;
- r.x.ax = 0x0003;
- int86(0x10, &r, &r);
- }
-
-
- void wait4retrace(void)
- {
- unsigned char i;
- do
- {
- i=inportb(0x3da);
- }
- while ((i & 8) !=0); /* while in retrace */
- do
- {
- i=inportb(0x3da);
- }
- while ((i & 8)==0); /* while not in retrace */
- /* retrace begins now */
- }
-
-
- void flippage()
- {//unsigned offset;
- if (visiblepage==vga)
- { visiblepage = vga+pagesize;
- activepage = vga;
- visiblestart = pagesize;
- activestart = 0;
- }
- else
- { visiblepage = vga;
- activepage = vga+pagesize;
- visiblestart = 0;
- activestart = pagesize;
- }
- // wait4retrace();
- outportb(0x3d4, 0x0C); /* set high byte */
- outportb(0x3d5, visiblestart >> 8);
- outportb(0x3d4, 0x0D); /* set low byte */
- outportb(0x3d5, visiblestart & 0xff);
-
- }
-
- void clearpage(int color,int pct = 100,int r=1)
- // clear the active page to color
- // clear the top pct percent of the page
-
- // r = retrace: apparently, once the video starts to scan a page
- // of memory, it continues scaning that page down to the last pixel,
- // even if the view page has been changed. If the memory being
- // written to screen is overwritten, this can result in unwanted flicker.
-
- { // outportb(0x3c4, 0x02); // enable all planes
- // outportb(0x3c5, 0x0f );
- int size;
- if (pct<100) size = (int)((long)pageheight*pct/100) *pagewidth;
- else size = pagesize;
- if (r) wait4retrace();
- outport(0x3c4, 0x0f02);
-
- asm { les di, activepage
- mov ax, color
- mov ah, al
- mov dx,ax
- db 0x66 //eax
- shl ax,16
- mov ax,dx
- db 0x66
- xor cx,cx
- mov cx,size
- shr cx,2
- db 0xf3 //rep
- db 0x66 //stosd
- stosw
- }
- }
-
-
- void clearvga() // clear the all vga pages to 0
- {
- wait4retrace();
- outport(0x3c4, 0x0f02); // enable all planes
-
- asm { db 0x66
- mov di, 0
- les di,vga
- db 0x66 // eax
- mov ax, 0
- db 0x66
- xor cx,cx
- mov cx,0x3FFF
- db 0xf3 //rep
- db 0x66 //stosd
- stosw
- }
- }
-
- void enableplane(int plane)
- { outportb(0x3c4, 0x02); // enable write plane plane
- outportb(0x3c5, 0x01 << (plane & 3));
- }
-
-
-
-
-
-
- unsigned getpixel(int x, int y)
- { unsigned char *inptr;
- unsigned color;
-
- if (x<0 || y<0 || x>maxx || y>maxy) return(0);
- // enableReadplane(x)
- outportb(0x3ce, 0x04); // graph controller addr
- outportb(0x3cf, x & 3);
-
- inptr =(unsigned char *) activepage+y*pagewidth+(x>>2);//x/4;
- color = *inptr;
- return color;
-
- }
-
-
-
-
-
- void putpixel(int x,int y,int color)
- { char *outptr;
-
- if (x<0 || y<0 || x>maxx || y>maxy) return;
-
- enableplane(x);
- outptr = activepage+y*pagewidth+(x>>2);//x/4;
- *outptr = color;
- }
-
-
-
-
-
-
- //_____________________________________________________________________
-
- // virtual screen functions (x,y = 10,000 x 10,000; pixels = 640x480)
- // xmin,ymin,xmax,ymax are pixel values for window
- // You may want to write your own get & setviewport style function to
- // change these values.
-
- void setwindow(int left ,int top,int right, int bottom)
- { if (left >= 0 && top >= 0 && right <= maxx && bottom <= maxy
- && left <= right && top <= bottom)
- {xmin = left; ymin = top; xmax = right; ymax = bottom;}
- }
-
- void vplot(int x,int y,int color) // virtual coordinates
- { long ex,ey;
- char *outptr;
-
- ex = x;
- ex *= maxx+1;
- x = ex/10000;
- ey = y;
- ey *= maxy+1;
- y = ey/10000;
-
- if (x<xmin || y<ymin || x>xmax || y>ymax) return;
-
- enableplane(x);
- outptr =activepage+y*pagewidth+x/4;
- *outptr = color;
- }
-
-
-
-
-
- void ZFRputimage(void *p,int x, int y, int percent, int flip,int angle)
-
- // Take a bitmap, scale it by some percent, flip it about its vertical
- // or horizontal axis, rotate it counter clockwise by any number of
- // degrees, clip it to a window and write it to a 4-plane xmode page.
-
- // color 0 is transparent.
-
- // x,y are virtual 10k by 10k screen coordiates. The image is centered
- // around x,y
-
- // zoom is relative to a 640x480 pixel screen.
- // flip: 1=horizontal, 2=vertical, 3=both (0 = no flip)
-
- // image is clipped to global variables (xmin,ymin,xmax,ymax);
-
- // note zoom and rotate are converted to floating point immediatly.
- // If you want use floating point zoom and rotate, just substitute
- // double pct and ang for int percent and angle in the parameter list.
-
- {
- long isin,icos,isin1,icos1,isin2,icos2;
- long ex,ey,xofs,yofs,halfy,halfx,wl,hl;
- char *inptr,*outptr;
- unsigned int wy,inofs,outofs;
- int w,h,x1,x2,y0,y1,y2,temp;
- double pct,ang;
- double sinx,cosx;
- int plane;
-
- pct = percent;
- pct /= 100;
-
- ang = angle;
- ang *= M_PI/180;
-
- //int maxx = getmaxx(); // maxx and maxy are screen boundries
- //int maxy = getmaxy(); // rather than buffer boundries.
-
- inptr =(char*) p + 4;
- //getgrafsize(p,&w,&h);
- w = *(int*)p+1;
- h = *((int*)p+1)+1;
- wl = 65536L*w;
- hl = 65526L*h;
-
- //convert x,y from virtual 10000x10000 coordinates to screen coordinates
- ex = x;
- ex *= maxx+1;
- x = ex/10000;
-
- ey = y;
- ey *= maxy+1;
- y = ey/10000;
-
-
- // find center pixel (on the texture map)
- halfx = ((w-1)/2)*65536L+32767L;
- halfy = ((h-1)/2)*65536L+32767L;
-
- // check for inbounds
- if (pct <= 0) // plot the center pixel
- { if (x<0 || y<0 || x>xmax || y>ymax) return;
- inofs =(int)(long)( 4+(halfx>>16)+(halfy>>16)*w);
- enableplane(x);
- outptr =activepage+y*pagewidth+x/4;
- *outptr = *((char *)p+inofs);
- return;
- }
-
- // scale image relative to a 640x480 screen
- double xfactor =pct*(maxx+1)/640;
- double yfactor =pct*(maxy+1)/480;
-
- sinx = sin(ang);
- cosx = cos(ang);
- // note: for better optimization, this should probably be done earlier
- // in the code. That will give the coprocessor time to do the
- // calculations while the CPU is busy doing other stuff.
-
- // convert the sine and cosine to fixed point
- isin = sinx*65536L;
- icos = cosx*65536L;
- isin1 = isin /xfactor;
- icos1 = icos /xfactor;
-
- if (flip % 2) icos1 = -icos1;
- if (flip > 1) isin1 = -isin1;
-
- isin2 = (isin1<<18) + ((isin1>>14) & 0xffff); // 4x
- icos2 = (icos1<<18) + ((icos1>>14) & 0xffff);
- // x factor is shifted an extra 2 bits since xmode plots every fourth pixel
-
- isin /= yfactor;
- icos /= yfactor;
- if (flip % 2)
- isin = -isin;
- if (flip>1)
- icos = -icos;
-
- // calculate y1 and y2(h2)
- if (flip % 2)
- halfx = (w/2)*65536L+32767L;
- if (flip > 1)
- halfy = (h/2)*65536L+32767L;
- temp = (short int)((long)(65536L*y+(sinx*halfx
- -cosx*halfy)*yfactor)>>16);
- y0 = temp;
- y1 = temp;
- temp = (short int)((long)(65536L*y+(sinx*halfx
- +cosx*(h*65536L-halfy))*yfactor)>>16);
- setmin(y0,temp);
- setmax(y1,temp);
- temp = (short int)((long)(65536L*y+(-sinx*(w*65536L-halfx)
- +cosx*(h*65536L-halfy))*yfactor)>>16);
- setmin(y0,temp);
- setmax(y1,temp);
- temp = (short int)((long)(65536L*y+(-sinx*(w*65536L-halfx)
- -cosx*(halfy))*yfactor)>>16);
- setmin(y0,temp);
- setmax(y1,temp);
-
- y0++;
- y1++;
- if (flip%2)
- halfx = ((w-1)/2)*65536L+32767L;
- if (flip>1)
- halfy = ((h-1)/2)*65536L+32767L;
-
- setmax(y0,ymin);
- setmin(y1,ymax+1);
-
- // Image is plotted about x,y
-
- for(plane = 0; plane<4; plane++)
- { enableplane(plane);
-
- ex =(long)(halfx+isin*(y-y0));
- ey =(long)(halfy-icos*(y-y0));
- for(y2=y0;y2<y1;y2++)
- // y0 = top screen row
- // y2 = current screen row
- // y1 = bottom screen row
- // ex,ey = 16.16 fixed point u,v values of x,y2 (bitmap x,y)
-
- // the following equations are derived from
- // 0 <= ex+(x2-x)*icos1 < w; 0 <= ey+(x2-x)*isin1 < h;
-
- // { u = ex+(x2-x)*icos1;
- // v = ey+(x2-x)*isin1;
- // if (u>=0 and u<w and v>=0 and v<h) plot(u,v -> x2,y2)
- // }
- {
- x1=xmin;x2=xmax+1;
- if (icos1>0)//((angle < 90)||(angle >270))
- { if(ex<0) temp =(int)(long)(-(ex-1)/icos1+1+x);
- else temp = (int)(long)(-ex/icos1+x);
- if (temp>x1) x1=temp;
- if(wl-ex<0)temp = (int)(long)((wl-ex)/icos1+x);
- else temp = (int)(long)((wl-ex-1)/icos1+x+1);
- if (temp<x2) x2=temp;
- }
- else if(icos1<0)//((angle >90)&&(angle < 270))
- { if(wl-ex<0)temp = (int)(long)((wl-ex-1)/icos1+1+x);
- else temp = (int)(long)((wl-ex)/icos1+x);
- if (temp>x1) x1=temp;
- if(ex<0)temp = (int)(long)(-(ex)/icos1+x);
- else temp = (int)(long)((-ex-1)/icos1+1+x);
- if (temp<x2) x2=temp;
- }
- else
- if (ex<0 || (ex>>16) >= w) goto nexty;
-
- if(isin1>0)//((angle > 0 )&&(angle <180))
- { if (ey<0) temp = (int)(long)(-(ey-1)/isin1+1+x);
- else temp = (int)(long)(-(ey)/isin1+x);
- if (temp>x1) x1=temp;
- if (hl-ey<0) temp = (int)(long)((hl-ey)/isin1+x);
- else temp = (int)(long)((hl-ey-1)/isin1+1+x);
- if (temp<x2) x2 = temp;
- }
- else if (isin1<0)//(angle > 180)
- { if(hl-ey<0)temp = (int)(long)((hl-ey-1)/isin1+1+x);
- else temp = (int)(long)((hl-ey)/isin1+x);
- if (temp>x1) x1=temp;
- if (ey<0) temp = (int)(long)(-(ey)/isin1+x);
- else temp = (int)(long)(-(ey-1)/isin1+1+x);
- if (temp<x2) x2 = temp;
- }
- else
- if (ey<0 || (ey>>16) >= h) goto nexty;
-
- // round up to the nearest (4+plane)
- x1 += (plane+4-(x1&3))&3;
-
- if(x2<0)x2=0;if(x1>=x2) goto nexty;
-
- xofs = ex+icos1*(x1-x);
- yofs = ey+isin1*(x1-x);
- wy = (int)(long)(w * (yofs>>16));
-
- outofs = y2*pagewidth + x1/4;
- outptr = activepage + outofs;
-
- // x2=0;
- // while (x2<w2)
- asm { push ds
- mov ebx, xofs
- mov edx, yofs
- ror ebx, 16
- ror edx, 16
- lds si, inptr
- add si, wy
- les di, outptr
- mov cx,x2
- dec cx
- sub cx,x1
- shr cx,2 // width /= 4 for unchained mode
- inc cx
- jcxz zfrdone
- xor dx,dx
- cmp word ptr isin2, 0 // if sin (angle) >= 0
- jl zfrlooptop2
- }
- zfrlooptop:
- asm {
- // color=*(p + inofs);
- mov al, [bx+si]
- cmp al,0
- jz zfrskipwrite
- // *(p2+outofs)=color;
- mov es:[di], al
- }
- zfrskipwrite:
- asm {
- // outofs++;
- inc di
- // xofs += icos;
- add ebx, icos2
- adc bx,0
- // yofs += isin;
- add edx, isin2
- adc dx,0
- // if (dy>0)
- jz zfrnext
- }
- incy: // inofs += dy*w;
- asm { add si,w
- dec dx
- jnz incy
- }
- zfrnext:
- asm { loop zfrlooptop
- jmp zfrdone
- }
- zfrlooptop2:
- asm {
- // color=*(p + inofs);
- mov al, [bx+si]
- // if (color != 0)
- cmp al,0
- jz zfrskipwrite2
- // *(p2+outofs)=color;
- mov es:[di], al
- }
- zfrskipwrite2:
- asm {
- // outofs++;
- inc di
- // xofs += icos;
- add ebx, icos2
- adc bx,0
- // yofs += isin;
- add edx, isin2
- adc dx,0
- // if (ax != *y)
- jz zfrnext2
- }
- decy:
- asm {
- sub si,w // add si,ws
- inc dx
- jnz decy
- }
- zfrnext2:
- asm { loop zfrlooptop2
- }
-
-
- zfrdone:
- asm { pop ds
- }
- nexty:
- ex -= isin;
-
- ey += icos;
- // outptr += w2;
- }
- } // next plane
- }
- // note: although the variables u and v appear in my notes, they do not
- // appear in the code. I wrote this code before I came across any
- // literature on texture mapping. The variables that most closely
- // correspond to this are ex,ey,xofs,and yofs
-
-
-
-
-
-
-